<template>
  <!-- type="number" -->
  <v-text-field
    :label="label"
    :placeholder="placeholder"
    :dense="dense"
    :disabled="disabled"
    :readonly="readonly"
    :color="readonly?'grey':''"
    :clearable="clearable&&!disabled&&!readonly"
    :hide-details="hideDetails"
    v-model="val"
    :max="max"
    :min="min"
    :rules="getRules"
    :counter="counter"
    :maxlength="maxlength"
    @input.native="numTnput"
    @blur="blur"
    @keyup.13="enterTap"
    @keyup.delete="deleteTap"
    @click:clear="clearTap"
  >
    <template v-slot:prepend-inner>
      <span v-if="!disabled&&!readonly&&required" class="require-star lh-30">*</span>
      <slot name="prepend-inner" />
    </template>
  </v-text-field>
</template>
<script lang="ts">
import { deepClone } from "@/utils";
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
import { ValidateRules } from "@/utils/ValidateRules";
@Component({})
export default class XNumber extends Vue {
  @Prop({ default: "" })
  label?: string;
  @Prop({ default: "" })
  placeholder?: string;
  @Prop({ default: true })
  dense?: boolean;
  @Prop({ default: false })
  disabled?: boolean;
  @Prop({ default: false })
  readonly?: boolean;
  @Prop({ default: true })
  clearable?: boolean;
  @Prop({ default: false })
  hideDetails?: boolean;
  @Prop()
  counter?: any;
  @Prop()
  maxlength?: any;
  @Prop({ default: Infinity }) //最大值
  max?: number;
  @Prop({ default: -Infinity }) //最小值
  min?: number;
  @Prop({ default: -1 }) // 小数点修正
  fix?: number;
  @Prop({ default: "" })
  value: any;
  @Prop({ default: ()=>[] }) rules?: any;
  @Prop({ default: false }) required?: boolean;
  NumberRules: any = [];
  lengthRule(value: any) {
    let fix = this.fix || -1;
    if (value && fix != -1) {
      if (String(value).split(".")[1].length > fix) {
        return `最多允许输入${this.fix}位小数，超出将自动截断`;
      }
    }
    return true;
  }
  @Watch("rules", { deep: true })
  rulesChange() {
    if (this.rules && this.rules.length) {
      this.NumberRules = deepClone(this.rules);
    }
    this.NumberRules.push(this.lengthRule);
  }

  private validateRules: any = ValidateRules;
  clear = false;
  val: any = "";
  get getRules() {
    return this.required ? [this.validateRules.required, ...this.rules] : this.rules
  }
  created() {
    this.rulesChange();
    let clear: any = this.clearable;
    this.clear = clear;
    if (clear === undefined) this.clear = true;
    if (clear === "") this.clear = true;
    this.val = "";
    this.valueChange();
  }
  @Watch("value")
  valueChange() {
    if (this.inputLock === null) {
      if (this.value != undefined && this.value !== "" && this.value != null) {
        if (this.fix && this.fix >= 0) {
          this.val = Number(this.value).toFixed(this.fix);
        } else {
          this.val = Number(this.value);
        }
      } else {
        this.val = this.value;
      }
    }
  }
  clearTap() {
    this.val = "";
    this.numChange();
  }
  inputLock: any = null;

  numChange() {
    this.$emit("input", this.val);
    this.$emit("change", this.val);
    if (this.inputLock !== null) {
      clearTimeout(this.inputLock);
    }
    this.inputLock = setTimeout(() => {
      this.inputLock = null;
    }, 100);
  }
  deleteTap() {
    if (!this.clear && this.val === "") {
      this.val = "";
      this.numChange();
    }
  }
  enterTap() {
    this.numChange();
  }
  numTnput(e: any) {
    let ele = e.target;
    let minus = "";
    let tempVal = this.val;
    //优化操作体验
    // if (this.clear == undefined && tempVal == "") tempVal = "0";
    if (tempVal == "00") tempVal = "0";
    tempVal = tempVal.replace(/^0([0-9])/, "$1");
    if (this.fix !== 0) {
      if (tempVal == ".") tempVal = "0.";
      if (tempVal == "-.") tempVal = "-0.";
      if (tempVal.indexOf(".") == -1 && tempVal != "-" && tempVal != "") {
        tempVal = String(Number(tempVal));
      }
      // 保存负号
      if (tempVal.indexOf("-") == 0) {
        minus = "-";
        tempVal = String(tempVal).slice(1, tempVal.length);
      }
      tempVal = String(tempVal)
        .replace(/[^\d\.]/g, "") //先把非数字的都替换掉，除了数字和.
        .replace(/^\./g, "") //必须保证第一个为数字而不是.
        .replace(/^0{2,}/, "0") //保证第一位只能有一个或0个0
        .replace(/^0[\d]/, "0") //以0开始的第二位只能为小数点
        .replace(/\.{2,}/g, ".") //保证只有出现一个.而没有多个.
        //保证.只出现一次，而不能出现两次以上
        .replace(".", "$#$")
        .replace(/\./g, "")
        .replace("$#$", ".");
    } else {
      tempVal = String(tempVal).replace(/[^0-9]/g, "");
    }
    let val: any = minus + tempVal;
    //数值校验
    let max = this.max || Infinity;
    this.max == 0 ? (max = 0) : (max = max);
    let min = this.min || -Infinity;
    this.min == 0 ? (min = 0) : (min = min);
    let fix: any = this.fix;
    if (val > max) val = max;
    if (val < min) val = min;

    // if (fix > 0) {
    //   if (String(val).indexOf(".") >= 0) {
    //     if (String(val).split(".")[1].length > fix) {
    //       val = Number(Number(val).toFixed(fix));
    //     }
    //   } else {
    //     val = Number(val);
    //   }
    // } else
    // if (fix == 0) {
    //   if (String(val).indexOf(".") > 0) {
    // val = val.replaceAll("[.]$", "")
    //   val = Number(val)
    //   }
    // }
    if (this.maxlength && String(val).length > this.maxlength)
      val = Number(String(val).slice(0, Number(this.maxlength)));
    ele.value = val;
    this.val = val;
    this.numChange();
  }
  blur() {
    if (this.readonly || !this.val) {
      return;
    }
    if (this.fix && this.fix >= 0) {
      this.val = Number(this.val).toFixed(this.fix);
      this.numChange();
    }
    this.$emit("blur", this.val);
  }
}
</script>
